package seatiger.tomcat.catalina.session;

import seatiger.tomcat.catalina.Context;
import seatiger.tomcat.catalina.Manager;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * session 的标准实现
 */
public class StandardSession extends StandardSession_middle{

    /**
     * session id
     */
    private String id = null;

    /**
     * session 的有效事件，单位是秒
     *
     * -1 的话表示不过期
     */
    protected int maxInactiveInterval = -1;

    /**
     * session 是否有效
     */
    protected boolean isValid = false;

    /**
     * session 的最后访问时间
     */
    protected long thisAccessedTime = 0L;

    /**
     * Session管理器
     */
    private Manager manager;

    private transient StandardSessionFacade facade = null;

    public StandardSession(Manager manager){
        this.manager = manager;
    }

    @Override
    public void setMaxInactiveInterval(int maxInactiveInterval) {
        this.maxInactiveInterval = maxInactiveInterval;
    }

    @Override
    public int getMaxInactiveInterval() {
        return maxInactiveInterval;
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    public HttpSession getSession() {
        return facade == null ? new StandardSessionFacade<>(this) : facade;
    }

    @Override
    public void setId(String id) {
        if (id == null && manager == null){
            return;
        }
        this.id = id;
        manager.add(this);
    }

    @Override
    public ServletContext getServletContext() {
        if (manager == null){
            return null;
        }
        Context context = (Context) manager.getContainer();
        return context.getServletContext();
    }

    @Override
    public void setValid(boolean valid) {
        isValid = valid;
    }

    @Override
    public boolean isValid() {
        if (!this.isValid) {
            return true;
        }
        if (maxInactiveInterval >= 0) {
            long timeNow = System.currentTimeMillis();
            int timeIdle = (int) ((timeNow - thisAccessedTime) / 1000L);
            if (timeIdle > maxInactiveInterval) {
                //失效了
                expire();
                System.out.println("session 过期了");
            }
        }
        return isValid;
    }

    @Override
    public void expire() {
        manager.remove(this);
        setValid(false);
    }

    @Override
    public void access() {
        thisAccessedTime = System.currentTimeMillis();
    }

    /**
     *  从流中读取数据
     * @param stream
     * @throws ClassNotFoundException
     * @throws IOException
     */
    public void readObjectData(ObjectInputStream stream) throws ClassNotFoundException, IOException {
        maxInactiveInterval = ((Integer) stream.readObject()).intValue();
        isValid = ((Boolean) stream.readObject()).booleanValue();
        thisAccessedTime = ((Long) stream.readObject()).longValue();
        id = (String) stream.readObject();
    }

    /**
     * 从流中读取数据
     * @param stream
     * @throws IOException
     */
    public void writeObjectData(ObjectOutputStream stream) throws IOException{
        stream.writeObject(new Integer(maxInactiveInterval));
        stream.writeObject(new Boolean(isValid));
        stream.writeObject(new Long(thisAccessedTime));
        stream.writeObject(id);
    }

    @Override
    public void setManager(Manager manager) {
        this.manager = manager;
    }

    @Override
    public long getLastAccessedTime() {
        return thisAccessedTime;
    }

    @Override
    public String toString() {
        return "StandardSession{" +
                "id='" + id + '\'' +
                ", maxInactiveInterval=" + maxInactiveInterval +
                ", isValid=" + isValid +
                ", thisAccessedTime=" + thisAccessedTime +
                ", manager=" + manager +
                ", facade=" + facade +
                '}';
    }
}
